import gitlab
from gitlab.exceptions import GitlabCreateError
import re
from config import *


def get_jira_num(project, from_, to):
    """
    对比2分支并提取其中的jira单号
    :param project: gitlab库的project对象
    :param from_: 目标分支
    :param to: 原分支
    :return: str
    """
    commit_title = ''
    result = project.repository_compare(from_, to)
    for commit in result['commits']:
        commit_title += commit['title']

    res = re.findall(r'SPDBK-\d*', commit_title)
    res = set(res)
    return '\n'.join(res)


def create_mrs(project_names, source_branch, target_branch, username=None):
    """
    提MR（支持多个工程）
    :param project_names: gitlab工程名（列表）
    :param source_branch: 源分支
    :param target_branch: 目标分支
    :param username: assign给谁
    :return: None
    """
    for project_name in project_names:
        project_id = gitlab_project_mapping.get(project_name)
        gl = gitlab.Gitlab(url=gitlab_url, private_token=personal_access_token)
        project = gl.projects.get(project_id)

        des = get_jira_num(project, target_branch, source_branch)

        try:
            mr = project.mergerequests.create({'source_branch': source_branch,
                                               'target_branch': target_branch,
                                               'title': f'From {source_branch} into {target_branch}',
                                               'description': des,
                                               'assignee_id': get_user_id(username),
                                               'remove_source_branch': False
                                               })
        except GitlabCreateError as e:
            print(f'{project_name} {e}')
            # 若已存在相应的mr，则仅打印web_url
            if re.findall(r'Another open merge request already exists for this source branch', str(e)):
                mr_id = re.findall(r'!(\d*)', str(e))[0]
                print(project.mergerequests.get(mr_id).web_url)
                continue
        else:
            print(mr.web_url)


def create_tags(project_names, version):
    """
    创建tags（包括release、master）
    :param project_names: gitlab工程名（列表）
    :param version: 版本名（eg: v2.26_0708）
    :return: None
    """
    for project_name in project_names:
        project_id = gitlab_project_mapping.get(project_name)
        gl = gitlab.Gitlab(url=gitlab_url, private_token=personal_access_token)
        project = gl.projects.get(project_id)

        release_tag = 'tag_release_' + version
        master_tag = 'tag_master_' + version
        release_branch = 'release/' + version

        try:
            project.tags.create({'tag_name': release_tag, 'ref': release_branch})
        except Exception as e:
            print(e)
        try:
            project.tags.create({'tag_name': master_tag, 'ref': 'master'})
        except Exception as e:
            print(e)
        print(f'{project_name} tag已打')


def check_tags(project_names, version):
    """
    检查realse tag与master tag是否存在
    :param project_names: gitlab工程名（列表）
    :param version: 版本名（eg: v2.26_0708）
    :return: None
    """
    flag = True
    for project_name in project_names:
        project_id = gitlab_project_mapping[project_name]
        gl = gitlab.Gitlab(url=gitlab_url, private_token=personal_access_token)
        project = gl.projects.get(project_id)

        release_tag = 'tag_release_' + version
        master_tag = 'tag_master_' + version
        try:
            tag = project.tags.get(release_tag)
            if tag.commit['title'] != f"Merge branch 'test/{version}' into 'release/{version}'":
                print(f'{project_name} {release_tag} 中分支错误 !!!')
                flag = False
        except Exception as e:
            print(f'{project_name} {release_tag} Not Found !!!')
            flag = False

        try:
            tag = project.tags.get(master_tag)
            if tag.commit['title'] != f"Merge branch 'release/{version}' into 'master'":
                print(f'{project_name} {master_tag} 中分支错误 !!!')
                flag = False
        except Exception as e:
            print(f'{project_name} {master_tag} Not Found !!!')
            flag = False

    if flag:
        print('Tags All Found ✓✓✓')


def check_mr(project_names, version):
    """
    检查 dev, test, release ,master分支是否完全一致
    :param project_names: gitlab工程名（列表）
    :param version: 版本名（eg: v2.26_0708）
    :return: None
    """
    flag = True
    for project_name in project_names:
        try:
            project_id = gitlab_project_mapping[project_name]
        except KeyError as e:
            print(f'{project_name} 在config.py中未找到')
            return
        gl = gitlab.Gitlab(url=gitlab_url, private_token=personal_access_token)
        project = gl.projects.get(project_id)

        dev_branch = 'dev/' + version
        test_branch = 'test/' + version
        release_branch = 'release/' + version

        try:
            result = project.repository_compare(test_branch, dev_branch)
            if result['commits']:
                print(f"{project_name} 的 {test_branch} 和 {dev_branch} 不一致")
                flag = False

            result = project.repository_compare(release_branch, test_branch)
            if result['commits']:
                print(f"{project_name} 的 {release_branch} 和 {test_branch} 不一致")
                flag = False

            # result = project.repository_compare('master', release_branch)
            # if result['commits']:
            #     print(f"{project_name} 的 master 和 {release_branch} 不一致")
            #     flag = False
        except Exception as e:
            print(f'{project_name} 相关信息未找到，请确认配置信息是否正确！（错误信息：{e}）')
            return

    if flag:
        print("dev, test, release, master分支完全一致 ✓✓✓")


def print_mr_info(project_names, mr_id):
    """打印merge信息"""
    for project_name in project_names:
        project_id = gitlab_project_mapping.get(project_name)
        gl = gitlab.Gitlab(url=gitlab_url, private_token=personal_access_token)
        project = gl.projects.get(project_id)

        mr = project.mergerequests.get(mr_id)
        mr.pprint()


def get_user_id(username):
    """通过username获取user_id"""
    if username is None:
        return
    gl = gitlab.Gitlab(url=gitlab_url, private_token=personal_access_token)
    user = gl.users.list(username=username)
    if user:
        return user[0].id
    else:
        print(f'未找到username: {username}')


if __name__ == '__main__':
    v0805 = ['warehouse-scheduler', 'e-statement-system', 'e-statement-be', 'real-time-inquiry-be',
             'warehouse-metadata-sys', 'deploy_data_sqls', 'warehouse-keystats-api']
    source_branch = 'test/v2.28_0805'
    target_branch = 'release/v2.28_0805'

    check_mr(v0805, 'v2.28_0805')

    # create_mrs(v0805, source_branch, target_branch, 'xueqin.wang')
    # create_mrs(['warehouse-scheduler'], source_branch, target_branch, 'xueqin.wang')
